import random
from typing import Dict,Union


from work.test3 import accounts


class Address:
    def __init__(self,  country:str,province:str,street:str,door:str):
        self.country = country
        self.province = province
        self.street = street
        self.door = door
    def __str__(self):
        return f"{self.country} {self.province} {self.street} {self.door}"
class User:
    def __init__(self,account:str,name:str,password:int,address:Address,balance:int,bank_name:str):
        self.account = account
        self.name = name
        self.password = password
        self.address = address
        self.balance = balance
        self.bank_name = bank_name
    def __str__(self):
        return (
            f"当前账户：{self.account}\n"
            f"密码： {self.password}\n"
            f"余额：{self.balance}元\n"
            f"居住地址:{self.address}\n"
            f"开户行:{self.bank_name}"
        )
    #银行类
class Bank:
        def __init__(self,name:str):
            self.name = name
            self.users:Dict[str,User] = {}
            self.max_users=100
        def add_user(self,user:User):
            if len(self.users) >=self.max_users:
                return 3
            if user.account in self.users:
                return 2
            self.users[user.account] = user
            return 1
        def deposit(self,account:str,amount:int):
            user=self.users.get(account)
            if not user:
                return False
            user.balance += amount
            return  True
        def withdraw(self,account:str,password:int,amount:int):
            user=self.users.get(account)
            if not user:
                return 1
            if user.password != password:
                return 2
            if user.balance < amount:
                return 3
            user.balance-=amount
            return 0
        def transfer(self,from_acc:str,to_acc:str,password:int,amount:int):
            sender=self.users.get(from_acc)
            receiver=self.users.get(to_acc)
            if not (sender and receiver):
                return 1
            if sender.password!=password:
                return 2
            if sender.balance<amount:
                return 3
            sender.balance-=amount
            receiver.balance+=amount
            return 0
        def query_account(self,account:str,password:int):
            "账户查询"
            user=self.users.get(account)
            if not user:
                print("该用户不存在")
                return None
            if user.password!=password:
                print("密码错误！")
                return None
            return user
def generate_account():
    while True:
        account=str(random.randint(10**7,10**8-1))
        if account not in bank.users:
            return account
def validate_password(pwd:str):
    return pwd.isdigit() and len(pwd)==6
class BankUI:
    def __init__(self,bank:Bank):
        self.bank=bank
    def show_menu(self):
        while True:
            print("\n===银行系统菜单===")
            print("1.开户")
            print("2.存款")
            print("3.取款")
            print("4.转账")
            print("5.查询")
            print("6.退出")
            choice=input("请选择操作：")
            {
                "1":self.open_account,
                "2":self.handle_deposit,
                "3":self.handle_withdraw,
                "4":self.handle_transfer,
                "5":self.handle_query,
                "6":lambda:exit()
            }.get(choice,lambda:print("无效输入!"))()
    def open_account(self):
        print("\n===开户业务===")
        name=input("请输入姓名：").strip()
        while True:
            pwd=input("请输入6位数字密码：").strip()
            if validate_password(pwd):
                break
            print("密码格式错误！")
        print("请输入地址信息：")
        addr=Address(
            country=input("国家：").strip(),
            province=input("省份：").strip(),
            street=input("街道：").strip(),
            door=input("门牌号：").strip()
        )
        new_user=User(
            account=generate_account(),
            name=name,
            password=int(pwd),
            address=addr,
            balance=0,
            bank_name=self.bank.name
        )
        result=self.bank.add_user(new_user)
        if result==1:
            print(f"开户成功！您的账号：{new_user.account}")
        elif result==2:
            print("操作失败：用户已存在")
        else:
            print("操作失败，用户库已满")
    def handle_deposit(self):
        "存款处理"
        print("\n===存款业务===")
        acc=input("请输入账户：").strip()
        amount=int(input("存款金额："))
        if self.bank.deposit(acc,amount):
            print("存款成功！")
        else:
            print("操作失败：账户不存在")
    def handle_withdraw(self):
        "取款处理"
        print("\n===取款业务===")
        acc=input("请输入账户：").strip()
        pwd=int(input("请输入密码："))
        amount=int(input("取款金额："))
        result=self.bank.withdraw(acc,pwd,amount)
        if result==0:
            print("取款成功！")
        elif result==1:
            print("操作失败：账户不存在")
        elif result==2:
            print("操作失败：密码错误")
        else:
            print("操作失败：余额不足")
    def handle_transfer(self):
        print("\n===转账业务===")
        from_acc=input("转出账户：").strip()
        to_acc=input("转入账户：").strip()
        pwd=int(input("转出账户密码："))
        amount=int(input("转账金额："))
        result=self.bank.transfer(from_acc,to_acc,pwd,amount)
        if result==0:
            print("转账成功！")
        elif result==1:
            print("操作失败：账户不存在")
        elif result==2:
            print("操作失败：密码错误")
        else:
            print("操作失败：余额不足")
    def handle_query(self):
        "账户查询"
        print("\n===账户查询===")
        acc=input("请输入账号；").strip()
        pwd=int(input("请输入密码："))
        user=self.bank.query_account(acc,pwd)
        if user:
            print("\n===账户信息===")
            print(user)
if __name__=="__main__":
    bank=Bank("中国工商银行昌平支行")
    ui=BankUI(bank)
    test_addr=Address("中国","北京","回龙观东大街","001号")
    test_user=User(
        account="12345678",
        name="测试用户",
        password=123456,
        address=test_addr,
        balance=10000,
        bank_name=bank.name
    )
    bank.add_user(test_user)
    ui.show_menu()